package softtech.apps.autoanswerphonecall;

import java.io.File;
import java.io.IOException;
import java.util.List;

import softtech.apps.autoanswerphonecall.R;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Environment;
import android.os.Handler;
import android.telephony.PhoneStateListener;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;

import com.android.internal.telephony.ITelephony;

public class MyPhoneStateListener extends PhoneStateListener {

	private final String AUDIO_RECORDER_FOLDER = "VoiceMessage";
	private File folder;
	private File files[];
	
	ITelephony m_telInterface;

	private int currentFormat = 0;
	private String path_record = "";
	String incoming_nr = "";
	boolean isRecording = false;

	Context context;
	int mode;
	// private File files[];
	DatabaseHandler db;
	List<Config> cfg;
	int enable = 0;
	int enableVoice = 0;
	int enableSMS = 0;
	int audio_value = -1;
	int receive_voice_message;
	boolean recording = false;
	private boolean has_sent = false;
	private boolean has_call = false;

	private String MUSIC = "MUSIC";
	public static String incomingPhoneNumber;
	int prev_state = 0;

	private final String TAG = "CallControl";
	private String incomingNumber;
	private ITelephony telephonyService = null;

	private boolean wasRinging = false;
	private boolean wasInCall = false;
	public boolean inCall = false;

	public MyPhoneStateListener(Context context) {
		super();
		// TODO Auto-generated constructor stub

		String filepath = Environment.getExternalStorageDirectory().getPath();
		folder = new File(filepath, AUDIO_RECORDER_FOLDER);
		if (!folder.exists()) {
			folder.mkdirs();
		}
		files = folder.listFiles();
		
		this.context = context;
		db = new DatabaseHandler(context);
		// get all config here

		cfg = db.getAllConfigs();
		if (cfg.size() > 0) {
			enable = cfg.get(0).get_value();
			enableVoice = cfg.get(1).get_value();
			enableSMS = cfg.get(2).get_value();
		}

		// Get config to auto record voice call here


		// Log.d("ENABLE", " Enable = " + enable + " Voice =" + enableVoice
		// + " SMS =" + enableSMS);

		if (enableVoice == 1) {
			mode = 1;
		} else{
			mode = 2;
		}

		Config cfgAudio = db.getConfig(4);
		audio_value = cfgAudio.get_value();

		// Message voice
		Config cfgVoiceMessage = db.getConfig(5);
		receive_voice_message = cfgVoiceMessage.get_value();
		Log.d("RECORD_VOICE", " Record = " + receive_voice_message);
		Log.d("MODE", "++++++ MODE = " + mode);

	}

	@Override
	public void onCallStateChanged(int state, final String incomingNumber) {
		// TODO Auto-generated method stub
		super.onCallStateChanged(state, incomingNumber);
			
		Log.d("STATE", "State = " + state);
		Log.d("STATE", "+++Incoming number = " + incoming_nr);
		Log.d("STATE", "++++++isIncomingCall = " + PhoneCallReceiver.isIncommingCall);
		
		
		AudioManager am = (AudioManager) context
				.getSystemService(Context.AUDIO_SERVICE);

		// get voice path of audio file and play

		/**
		 * Set config for media player onCompletion,onPrepared
		 * */
		MediaPlayer mediaPlayer = new MediaPlayer();

		mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
			@Override
			public void onCompletion(MediaPlayer mp) {
				// TODO Auto-generated method stub
				mp.stop();
				mp.reset();
				mp.release();
				mp = null;

				Log.d(MUSIC, "Music player has finish");

				/**
				 * When music has played done -> send intent to
				 * VoiceMessageActivity Start record during the call
				 * */

				// release audio file and send intent to begin record
				// if (receive_voice_message == 1 && recording == true) {
				// Intent in = new Intent("startRecordVoiceMessage");
				// in.putExtra("StartVoiceMessage", "startHere");
				// in.putExtra("IncomingPhone", incomingNumber.toString());
				// context.sendBroadcast(in);
				// }

			}

		});

		mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
			@Override
			public void onPrepared(MediaPlayer mp) {
				// Do something. For example: playButton.setEnabled(true);
//				mp.start();
			}
		});
		
		
		/**
		 * do something with state change CALL_STATE_RINGING, CALL_STATE_IDLE,
		 * CALL_STATE_IDLE
		 * */
		switch (state) {
		
		case TelephonyManager.CALL_STATE_RINGING :
			if(PhoneCallReceiver.isIncommingCall == 1){
				
				if(incomingNumber != ""){
					incoming_nr = incomingNumber;
				}
				Log.d(TAG, "CALL_STATE_RINGING");
				prev_state = state;
				if (mode == 2) {

					/**
					 * Reject a call and auto send a SMS to caller General a
					 * notification
					 * */

					// rejectCall(context);
					// Set mode slient
					am.setRingerMode(AudioManager.RINGER_MODE_SILENT);

					has_sent = false;
					Log.e("CALL", "---->>>>>>>>>> Reject a call");

				} else if (mode == 1) {
					
					am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
					Log.d(TAG, "Mode = " + mode);

					/**
					 * Accept a call and forward to CALL_STATE_OFFHOOK state
					 * */
					has_call = false;
					AppCacheData acd = new AppCacheData();
					String enable = acd.LoadCache(context, "broadcast");
					if (enable.trim().equals("1")) {
						
						
						if(receive_voice_message == 1){
							
							Log.e(TAG, "SEND INTENT BAT DAU CHO MY BROADCAST");
							Intent in = new Intent(ConstantApp.RECORD_INTENT_NAME);
							in.putExtra(ConstantApp.RECORD_EXTRA_NAME, "startHere");
							context.sendBroadcast(in);
							//answerRingingCall();
						
							acceptCall(context);
							generateNotification(context,
									"Just sent accept a call from " + incoming_nr);
//							Handler hand = new Handler();
//							hand.postDelayed(new Runnable() {
//								
//								@Override
//								public void run() {
//									
//								}
//							}, 1000);
						}

						
						Log.e("BAT_MAY", "FUCK = " + enable);
					} else {
						Log.e("DEO_BAT_MAY", "FUCK = " + enable);
					}

				}
			}
			
			

			break;
		case TelephonyManager.CALL_STATE_IDLE:
			Log.e(TAG, "+++++++++ CALL_STATE_IDLE ");
			if(PhoneCallReceiver.isIncommingCall == 1){
				
				
				Log.d(TAG, "CALL_STATE_IDLE==>" + incoming_nr);
				if ((prev_state == TelephonyManager.CALL_STATE_OFFHOOK)) {
					prev_state = state;
					// Answered Call which is ended
					
					am.setSpeakerphoneOn(false);
					mediaPlayer.stop();
					mediaPlayer.reset();
					mediaPlayer.release();
					mediaPlayer = null;
				
				}
				if ((prev_state == TelephonyManager.CALL_STATE_RINGING)) {
					prev_state = state;
					// Rejected or Missed call
					/**
					 * if mode == 2 -> Reject a call and send a message to caller
					 * */
					if (mode == 2) {
						// Send SMS From here
						String mes = "";
						List<Message> messageChoose = db.getAllMessages();
						for (Message m : messageChoose) {
							if (m.get_is_choose() == 1) {
								mes = m.get_message();
								break;
							}
						}
						// mes = messageChoose.get_message();
						if (mes == "") {
							mes = "I'm busy !!";
						}
						sendSMSMessage(incomingNumber, mes);
						generateNotification(context, "Just sent a messsage to "
								+ incomingNumber);

					}
				}
			}else if(receive_voice_message == 1){
				Log.e(TAG, "SEND INTENT KET THUC CHO MY BROADCAST");
				Intent in = new Intent(ConstantApp.RECORD_INTENT_NAME);
				in.putExtra(ConstantApp.RECORD_EXTRA_NAME, "stopHere");
				context.sendBroadcast(in);
			}
			
			break;

		case TelephonyManager.CALL_STATE_OFFHOOK:
			if(PhoneCallReceiver.isIncommingCall == 1){
				Log.d(TAG, "CALL_STATE_OFFHOOK");

				prev_state = state;
				/**
				 * Start an established. State CALL_STATE_OFFHOOK = When user
				 * accept a call
				 * */
				recording = true;
				// if (!has_call) {
				/**
				 * Set mode and configuration for state CALL_STATE_OFFHOOK set
				 * Speaker = On -> to play voice record set max volume
				 * AudioManager.STREAM_MUSIC
				 * */
				am.setMode(AudioManager.MODE_IN_CALL);
				am.setSpeakerphoneOn(true);
				
				am.setStreamVolume(AudioManager.STREAM_MUSIC,
						am.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);

				// Get sound source from database depend on -> audio_value

				Log.d("AUDIO_VALUE", "Audio value = " + audio_value);
				if (audio_value != -1) {

					// Problem about the path of file
					// file://sdcard/test/"+ date.toString() + ".3gp

					String filePath = files[audio_value].getAbsolutePath()
							.toString();
					Log.d(MUSIC, "Duong dan file am thanh = " + filePath);
					try {
						mediaPlayer.setDataSource(filePath);
					} catch (IllegalArgumentException e) {
						
						e.printStackTrace();
					} catch (SecurityException e) {
						
						e.printStackTrace();
					} catch (IllegalStateException e) {
						
						e.printStackTrace();
					} catch (IOException e) {
						
						e.printStackTrace();
					}
					Log.d("Media", "--------->From voice message folder");
					
					
					// MODE_IN_CALL = Dang ket noi
					// am.getStreamMaxVolume(AudioManager.STREAM_MUSIC)

					mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
					mediaPlayer.setVolume(AudioManager.MODE_IN_CALL,
							AudioManager.MODE_IN_CALL);
					mediaPlayer.setLooping(false);

					try {
						mediaPlayer.prepare();
					} catch (IllegalStateException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
					mediaPlayer.start();
				}else{
					try {
						mediaPlayer = MediaPlayer.create(context,R.raw.leave_message_please);
					} catch (IllegalArgumentException e) {
						
						e.printStackTrace();
					} catch (SecurityException e) {
						
						e.printStackTrace();
					} catch (IllegalStateException e) {
						
						e.printStackTrace();
					}
					Log.d("Media", "--------->From RAW");

					mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
					mediaPlayer.setVolume(AudioManager.MODE_IN_CALL,
							AudioManager.MODE_IN_CALL);
					mediaPlayer.setLooping(false);

					try {
						mediaPlayer.prepare();
					} catch (IllegalStateException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
					mediaPlayer.start();

				}

			}
			
			break;

		default:
			// mediaPlayer.stop();
			// mediaPlayer.reset();
			// mediaPlayer.release();
			// mediaPlayer = null;
			break;
		}

	}

	/**
	 * More functions
	 * 
	 * */
	protected void sendSMSMessage(final String phoneNo, final String message) {
		try {
			SmsManager smsManager = SmsManager.getDefault();
			smsManager.sendTextMessage(phoneNo, null, message, null, null);
			// show notification here
			String noti_ok = "Message just sent to " + phoneNo;
			generateNotification(context, noti_ok);
		} catch (Exception e) {
			// show notification here
			String noti_failed = "Message Send Failure to " + phoneNo;
			generateNotification(context, noti_failed);
			e.printStackTrace();
		}
	}

	private void rejectCall(Context context) {
		Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);
		buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(
				KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
		context.sendOrderedBroadcast(buttonDown,
				"android.permission.CALL_PRIVILEGED");

		// froyo and beyond trigger on buttonUp instead of buttonDown
		Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);
		buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(
				KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
		context.sendOrderedBroadcast(buttonUp,
				"android.permission.CALL_PRIVILEGED");
	}

	// Accept an incoming call
	public static void acceptCall(Context context) {

		Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);
		buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(
				KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
		context.sendOrderedBroadcast(buttonDown,
				"android.permission.CALL_PRIVILEGED");

		// froyo and beyond trigger on buttonUp instead of buttonDown
		Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);
		buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(
				KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
		context.sendOrderedBroadcast(buttonUp,
				"android.permission.CALL_PRIVILEGED");
	}

	// show notification

	/*
	 * Issues a notification to inform the user that server has sent a message.
	 */
	private static void generateNotification(Context context, String message) {
		int icon = R.drawable.app_icon;
		long when = System.currentTimeMillis();
		NotificationManager notificationManager = (NotificationManager) context
				.getSystemService(Context.NOTIFICATION_SERVICE);
		Notification notification = new Notification(icon, message, when);

		String title = context.getString(R.string.app_name);

		Intent notificationIntent = new Intent(context, MainActivity.class);
		// set intent so it does not start a new activity
		notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
				| Intent.FLAG_ACTIVITY_SINGLE_TOP);
		PendingIntent intent = PendingIntent.getActivity(context, 0,
				notificationIntent, 0);
		notification.setLatestEventInfo(context, title, message, intent);
		notification.flags |= Notification.FLAG_AUTO_CANCEL;

		// Play default notification sound
		// notification.defaults |= Notification.DEFAULT_SOUND;

		// Vibrate if vibrate is enabled
		// notification.defaults |= Notification.DEFAULT_VIBRATE;
		notificationManager.notify(0, notification);

	}
	private synchronized void answerRingingCall() {
		try {
			Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG);
			localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
			localIntent1.putExtra("state", 1);
			localIntent1.putExtra("microphone", 1);
			localIntent1.putExtra("name", "Headset");
			context.sendOrderedBroadcast(localIntent1,
					"android.permission.CALL_PRIVILEGED");

			Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON);
			KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN,
					KeyEvent.KEYCODE_HEADSETHOOK);
			localIntent2.putExtra("android.intent.extra.KEY_EVENT",
					localKeyEvent1);
			context.sendOrderedBroadcast(localIntent2,
					"android.permission.CALL_PRIVILEGED");

			Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON);
			KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,
					KeyEvent.KEYCODE_HEADSETHOOK);
			localIntent3.putExtra("android.intent.extra.KEY_EVENT",
					localKeyEvent2);
			context.sendOrderedBroadcast(localIntent3,
					"android.permission.CALL_PRIVILEGED");

			Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG);
			localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
			localIntent4.putExtra("state", 0);
			localIntent4.putExtra("microphone", 1);
			localIntent4.putExtra("name", "Headset");
			context.sendOrderedBroadcast(localIntent4,
					"android.permission.CALL_PRIVILEGED");
		} catch (Exception e) {
			Log.i("answerRingingCall:", e.getMessage());
		}
	}

}
